package ch.reevolt.curchod.ui;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import ch.reevolt.curchod.database.DataBase;
import ch.reevolt.curchod.model.HistoricModel;
import ch.reevolt.curchod.model.MyTableCellRender;
import ch.reevolt.curchod.model.SearchModel;
import ch.reevolt.curchod.model.SearchModel.ModelType;
import data.Data;
import data.Employee;
import data.Tool;

public class MainFrame {

	private JFrame frmGestionDesOutils;
	private JTextField searchField;

	private JLabel status_label;

	private HistoricModel historicModel;
	private SearchModel searchModel;

	private JPanel panelHistory;

	private JTextField field_tool;
	private JTextField field_employee;
	private JTextField field_inout;
	private JTextField result_tool;
	private JTextField result_employee;
	private JTextField field_resultOnResearch;
	private JTextField field_scan;
	private Timer timer;

	private final Action exitAppAction = new ExitAppAction();
	private final Action connectionAction = new ConnectionAction();
	private final Action disconnectAction = new DisconnectAction();

	// image for UI
	private ImageIcon icon_work;
	private ImageIcon icon_search;
	private ImageIcon icon_user;
	private ImageIcon icon_history;
	private ImageIcon icon_tick;
	private ImageIcon icon_error;
	private ImageIcon icon_sync;
	private ImageIcon icon_user_large;
	private ImageIcon icon_tool_large;

	// status app
	enum Status {
		SYNC, ERROR, OK
	}

	private final int OUTPUT_CONST = 0;
	private final int INPUT_CONST = 1;
	private final char ESCAPE_CHAR = '\n';
	private JTable tableHistoric;
	private JTable tableSearch;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainFrame window = new MainFrame();
					window.frmGestionDesOutils.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public MainFrame() {
		try {
			initialize();
			new ConnectionPane();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Initialize the contents of the frame.
	 * 
	 * @throws
	 */
	private void initialize() throws IOException {

		GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();

		// load image
		icon_work = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/work.png")));
		icon_search = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/search.png")));
		icon_user = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/user.png")));
		icon_history = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/history.png")));
		icon_tick = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/tick.png")));
		icon_error = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/error.png")));
		icon_sync = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/sync.png")));
		icon_user_large = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/user_large.png")));
		icon_tool_large = new ImageIcon(ImageIO.read(MainFrame.class.getResource("/images/tool_large.png")));

		frmGestionDesOutils = new JFrame();
		
		frmGestionDesOutils.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				if(DataBase.getInstance().isConnected())
					DataBase.getInstance().closeConnection();
        System.exit(0);
      }
		});

		frmGestionDesOutils.setTitle("Gestion des outils");

		frmGestionDesOutils.setBounds(0, 0, 1024, 768);

		frmGestionDesOutils.setMaximizedBounds(e.getMaximumWindowBounds());
		frmGestionDesOutils.setExtendedState(frmGestionDesOutils.getExtendedState() | JFrame.MAXIMIZED_BOTH);

		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.LEFT);
		tabbedPane.setFont(new Font("Dialog", Font.BOLD, 16));

		JPanel panelWork = new JPanel();
		tabbedPane.addTab("", icon_work, panelWork);

		JLabel lblOutil = new JLabel("Outil :");
		lblOutil.setFont(new Font("Dialog", Font.BOLD, 26));

		field_tool = new JTextField();
		field_tool.setFocusable(false);

		field_tool.setFont(new Font("Dialog", Font.BOLD, 22));
		field_tool.setColumns(20);

		JLabel lblEmploy = new JLabel("Employé :");
		lblEmploy.setFont(new Font("Dialog", Font.BOLD, 26));

		field_employee = new JTextField();
		field_employee.setFocusable(false);

		field_employee.setFont(new Font("Dialog", Font.BOLD, 22));
		field_employee.setColumns(20);

		JLabel lblEntreSortie = new JLabel("Entrée / Sortie");
		lblEntreSortie.setFont(new Font("Dialog", Font.BOLD, 26));

		field_inout = new JTextField();
		field_inout.setFocusable(true);

		field_inout.setFont(new Font("Dialog", Font.BOLD, 22));
		field_inout.setColumns(20);

		status_label = new JLabel("", (Icon) null, SwingConstants.CENTER);
		setStatus(Status.SYNC);

		result_tool = new JTextField();
		result_tool.setEditable(false);
		result_tool.setFont(new Font("Dialog", Font.BOLD, 22));
		result_tool.setColumns(10);

		result_employee = new JTextField();
		result_employee.setEditable(false);
		result_employee.setFont(new Font("Dialog", Font.BOLD, 22));
		result_employee.setColumns(10);

		field_scan = new JTextField();
		field_scan.requestFocusInWindow();
		field_scan.setFont(new Font("Dialog", Font.BOLD, 22));
		field_scan.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {

				String field = field_scan.getText();

				if (e.getKeyChar() == ESCAPE_CHAR) {

					int number = Integer.parseInt(field);

					if (number == OUTPUT_CONST) {
						field_scan.setText("");
						field_inout.setText("sortie");
					} else if (number == INPUT_CONST) {
						field_scan.setText("");
						field_inout.setText("entrée");
					} else if (number % 2 == 0) {
						field_scan.setText("");

						Tool t = DataBase.getInstance().getTool(number);
						// tool doesn't exist
						if (t.name().compareTo("") == 0)
							setStatus(Status.ERROR);
						else {
							result_tool.setText(t.name() + " - " + t.description());
							field_tool.setText(field);
						}
					} else {
						field_scan.setText("");
						Employee employee = DataBase.getInstance().getEmployee(number);
						if (employee.name().compareTo("") == 0)
							setStatus(Status.ERROR);
						else {
							field_employee.setText(field);
							result_employee.setText(employee.name() + " " + employee.surname());
						}
					}

					if (!field_inout.getText().isEmpty() && !field_employee.getText().isEmpty()
							&& !field_tool.getText().isEmpty()) {

						Employee employee = DataBase.getInstance().getEmployee(Integer.parseInt(field_employee.getText()));
						Tool tool = DataBase.getInstance().getTool(Integer.parseInt(field_tool.getText()));

						if (field_inout.getText().compareTo("sortie") == 0) {
							if (DataBase.getInstance().output(employee, tool)) {
								setStatus(Status.OK);
							} else {
								setStatus(Status.ERROR);
							}
						} else {
							if (DataBase.getInstance().input(employee, tool)) {
								setStatus(Status.OK);
							} else {
								setStatus(Status.ERROR);
							}
						}
						field_employee.setText("");
						field_inout.setText("");
						field_tool.setText("");
					}
				}
			}
		});
		field_scan.setColumns(10);

		JLabel label = new JLabel("Scan :");
		label.setFont(new Font("Dialog", Font.BOLD, 26));

		GroupLayout gl_panelWork = new GroupLayout(panelWork);
		gl_panelWork.setHorizontalGroup(gl_panelWork.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panelWork
						.createSequentialGroup()
						.addGap(70)
						.addGroup(
								gl_panelWork
										.createParallelGroup(Alignment.LEADING)
										.addComponent(lblEmploy)
										.addComponent(lblOutil)
										.addComponent(status_label, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 768, Short.MAX_VALUE)
										.addGroup(
												gl_panelWork
														.createSequentialGroup()
														.addGroup(
																gl_panelWork
																		.createParallelGroup(Alignment.LEADING)
																		.addGroup(
																				gl_panelWork
																						.createParallelGroup(Alignment.TRAILING, false)
																						.addComponent(field_inout, Alignment.LEADING, 0, 0, Short.MAX_VALUE)
																						.addComponent(field_employee, Alignment.LEADING, 0, 0, Short.MAX_VALUE)
																						.addComponent(field_tool, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 239,
																								Short.MAX_VALUE)).addComponent(lblEntreSortie))
														.addPreferredGap(ComponentPlacement.RELATED)
														.addGroup(
																gl_panelWork.createParallelGroup(Alignment.LEADING)
																		.addComponent(label, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE)
																		.addComponent(result_employee, GroupLayout.DEFAULT_SIZE, 523, Short.MAX_VALUE)
																		.addComponent(result_tool, GroupLayout.DEFAULT_SIZE, 523, Short.MAX_VALUE)
																		.addComponent(field_scan, GroupLayout.DEFAULT_SIZE, 523, Short.MAX_VALUE))))
						.addContainerGap()));
		gl_panelWork.setVerticalGroup(gl_panelWork.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panelWork
						.createSequentialGroup()
						.addContainerGap()
						.addComponent(lblOutil)
						.addPreferredGap(ComponentPlacement.UNRELATED)
						.addGroup(
								gl_panelWork
										.createParallelGroup(Alignment.LEADING)
										.addGroup(
												gl_panelWork
														.createSequentialGroup()
														.addComponent(field_tool, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE).addGap(18).addComponent(lblEmploy))
										.addComponent(result_tool, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE))
						.addPreferredGap(ComponentPlacement.UNRELATED)
						.addGroup(
								gl_panelWork
										.createParallelGroup(Alignment.LEADING)
										.addComponent(field_employee, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(result_employee, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE))
						.addGap(18)
						.addGroup(
								gl_panelWork.createParallelGroup(Alignment.LEADING).addComponent(lblEntreSortie)
										.addComponent(label, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE))
						.addPreferredGap(ComponentPlacement.UNRELATED)
						.addGroup(
								gl_panelWork
										.createParallelGroup(Alignment.LEADING)
										.addComponent(field_inout, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(field_scan, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE)).addGap(93)
						.addComponent(status_label, GroupLayout.PREFERRED_SIZE, 409, GroupLayout.PREFERRED_SIZE)
						.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		panelWork.setLayout(gl_panelWork);

		JPanel panelRecherche = new JPanel();
		tabbedPane.addTab("", icon_search, panelRecherche);

		searchField = new JTextField();
		searchField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {

				if (e.getKeyChar() == ESCAPE_CHAR) {

					int code = Integer.parseInt(searchField.getText());

					ModelType type = ModelType.EMPLOYEE;

					if (code == 0) {
						field_resultOnResearch.setText("Toute les sorties");
						type = ModelType.IN_OUT;
					} else if (code == 1) {
						field_resultOnResearch.setText("Toute les entrées");
						type = ModelType.IN_OUT;
					} else if (code == 2) {
						field_resultOnResearch.setText("Outils à l'extérieur");
						type = ModelType.POSITION_OUT;
					} else if (code == 3) {
						field_resultOnResearch.setText("Outils en stock");
						type = ModelType.POSITION_STOCK;

					} else if (code % 2 == 0) {
						Tool t = DataBase.getInstance().getTool(code);
						field_resultOnResearch.setText(t.name() + " - " + t.description());
						type = ModelType.TOOL;
					} else if (code % 2 != 0) {
						Employee employee = DataBase.getInstance().getEmployee(code);
						field_resultOnResearch.setText(employee.name() + " " + employee.surname());
						type = ModelType.EMPLOYEE;
					}
					String[][] array = DataBase.getInstance().getHistoric(code);

					if (array == null) {
						field_resultOnResearch.setText("Aucune donnée");
					} else {

						searchModel.setType(type);
						searchModel.setContent(array);
						tableSearch.setModel(searchModel);
						searchModel.fireTableDataChanged();
					}
				}
			}
		});
		searchField.setFont(new Font("Dialog", Font.BOLD, 22));
		searchField.setColumns(41);

		/**
		 * tabbed pane listener
		 */
		tabbedPane.addChangeListener(new ChangeListener() {
			// This method is called whenever the selected tab changes
			public void stateChanged(ChangeEvent evt) {
				JTabbedPane pane = (JTabbedPane) evt.getSource();
				// Get current tab
				switch (pane.getSelectedIndex()) {
				case 0:
					field_scan.requestFocusInWindow();
					field_tool.setText("");
					field_employee.setText("");
					field_inout.setText("");
					field_scan.setText("");
					break;
				case 1:
					searchField.requestFocusInWindow();
					break;
				case 2:
					break;
				case 3:

					// get all historic and fill the table
					String[][] array = DataBase.getInstance().getHistoric();
					historicModel.setContent(array);

					historicModel.fireTableDataChanged();

					break;

				default:

				}
			}
		});

		JLabel lblCodeBar = new JLabel("Code Bar :");
		lblCodeBar.setFont(new Font("Dialog", Font.BOLD, 26));

		field_resultOnResearch = new JTextField();
		field_resultOnResearch.setEditable(false);
		field_resultOnResearch.setFont(new Font("Dialog", Font.BOLD, 22));
		field_resultOnResearch.setColumns(10);

		JScrollPane scrollPane_search = new JScrollPane();

		GroupLayout gl_panelRecherche = new GroupLayout(panelRecherche);
		gl_panelRecherche.setHorizontalGroup(gl_panelRecherche.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panelRecherche
						.createSequentialGroup()
						.addContainerGap()
						.addGroup(
								gl_panelRecherche
										.createParallelGroup(Alignment.LEADING)
										.addComponent(lblCodeBar)
										.addGroup(
												gl_panelRecherche
														.createSequentialGroup()
														.addGap(7)
														.addGroup(
																gl_panelRecherche
																		.createParallelGroup(Alignment.LEADING)
																		.addComponent(scrollPane_search, GroupLayout.DEFAULT_SIZE, 1065, Short.MAX_VALUE)
																		.addGroup(
																				gl_panelRecherche
																						.createSequentialGroup()
																						.addComponent(searchField, GroupLayout.PREFERRED_SIZE, 248,
																								GroupLayout.PREFERRED_SIZE)
																						.addPreferredGap(ComponentPlacement.RELATED)
																						.addComponent(field_resultOnResearch, GroupLayout.DEFAULT_SIZE, 811,
																								Short.MAX_VALUE))))).addContainerGap()));
		gl_panelRecherche.setVerticalGroup(gl_panelRecherche.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panelRecherche
						.createSequentialGroup()
						.addContainerGap()
						.addComponent(lblCodeBar)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(
								gl_panelRecherche
										.createParallelGroup(Alignment.LEADING)
										.addComponent(searchField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(field_resultOnResearch, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE)).addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(scrollPane_search, GroupLayout.DEFAULT_SIZE, 829, Short.MAX_VALUE).addContainerGap()));

		tableSearch = new JTable();
		tableSearch.setDefaultRenderer(Object.class, new MyTableCellRender());

		searchModel = new SearchModel();

		scrollPane_search.setViewportView(tableSearch);
		panelRecherche.setLayout(gl_panelRecherche);
		tableSearch.setAutoCreateRowSorter(true);

		JPanel panelManagement = new JPanel();
		tabbedPane.addTab("", icon_user, panelManagement);

		panelHistory = new JPanel();

		tabbedPane.addTab("", icon_history, panelHistory);

		historicModel = new HistoricModel();
		panelHistory.setLayout(new BorderLayout());

		JScrollPane scrollPane_historic = new JScrollPane();
		scrollPane_historic.setBounds(12, 12, 1000, 600);
		panelHistory.setLayout(new BorderLayout());
		panelHistory.add(scrollPane_historic);

		tableHistoric = new JTable(historicModel);
		tableHistoric.setDefaultRenderer(Object.class, new MyTableCellRender());
		scrollPane_historic.setViewportView(tableHistoric);
		tableHistoric.setAutoCreateRowSorter(true);

		JButton btnAjouterEmploy = new JButton(icon_user_large);

		btnAjouterEmploy.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new AddEmployee();
			}
		});
		btnAjouterEmploy.setFont(new Font("Dialog", Font.BOLD, 25));

		JButton btnAjouterOutil = new JButton(icon_tool_large);
		btnAjouterOutil.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new AddTool();
			}
		});
		btnAjouterOutil.setFont(new Font("Dialog", Font.BOLD, 25));
		GroupLayout gl_panelManagement = new GroupLayout(panelManagement);
		gl_panelManagement.setHorizontalGroup(gl_panelManagement.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panelManagement.createSequentialGroup().addGap(78).addComponent(btnAjouterEmploy).addGap(18)
						.addComponent(btnAjouterOutil).addContainerGap(340, Short.MAX_VALUE)));
		gl_panelManagement.setVerticalGroup(gl_panelManagement.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panelManagement
						.createSequentialGroup()
						.addGap(76)
						.addGroup(
								gl_panelManagement.createParallelGroup(Alignment.BASELINE).addComponent(btnAjouterEmploy)
										.addComponent(btnAjouterOutil)).addContainerGap(714, Short.MAX_VALUE)));
		panelManagement.setLayout(gl_panelManagement);

		GroupLayout groupLayout = new GroupLayout(frmGestionDesOutils.getContentPane());
		groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(Alignment.LEADING).addGroup(
				groupLayout.createSequentialGroup().addContainerGap()
						.addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, 998, Short.MAX_VALUE).addContainerGap()));
		groupLayout.setVerticalGroup(groupLayout.createParallelGroup(Alignment.LEADING).addGroup(
				groupLayout.createSequentialGroup().addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, 704, Short.MAX_VALUE)
						.addContainerGap()));

		frmGestionDesOutils.getContentPane().setLayout(groupLayout);

		JMenuBar menuBar = new JMenuBar();
		frmGestionDesOutils.setJMenuBar(menuBar);

		JMenu mnFichier = new JMenu("Fichier");
		menuBar.add(mnFichier);

		JMenuItem mntmConnection = new JMenuItem("Connexion");
		mntmConnection.setAction(connectionAction);
		mnFichier.add(mntmConnection);

		JMenuItem mntmDconnexion = new JMenuItem("Déconnexion");
		mntmDconnexion.setAction(disconnectAction);
		mnFichier.add(mntmDconnexion);

		JMenuItem mntmQuitter = new JMenuItem("Quitter");
		mntmQuitter.setAction(exitAppAction);
		mnFichier.add(mntmQuitter);

		JMenu mnAide = new JMenu("Aide");
		menuBar.add(mnAide);

		JMenuItem mntmPropos = new JMenuItem("à Propos");
		mnAide.add(mntmPropos);

	}

	public void setStatus(Status stat) {

		switch (stat) {
		case OK:
			status_label.setIcon(icon_tick);
			result_employee.setText("");
			result_tool.setText("");
			startTimer();
			break;
		case ERROR:
			status_label.setIcon(icon_error);
			startTimer();
			break;
		case SYNC:
			status_label.setIcon(icon_sync);
			break;
		}
	}

	private void startTimer() {
		timer = new Timer(2000, new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				setStatus(Status.SYNC);

			}
		});
		timer.setRepeats(false);
		timer.start();
	}

	private class ExitAppAction extends AbstractAction {
		public ExitAppAction() {
			putValue(NAME, "Quitter");
			putValue(SHORT_DESCRIPTION, "Quitter l'application");
		}

		public void actionPerformed(ActionEvent e) {
			if (DataBase.getInstance().isConnected())
				DataBase.getInstance().closeConnection();
			System.exit(0);
		}
	}

	private class ConnectionAction extends AbstractAction {
		public ConnectionAction() {
			putValue(NAME, "Connexion");
			putValue(SHORT_DESCRIPTION, "Se connecter à la base de données");
		}

		public void actionPerformed(ActionEvent e) {
			if (!DataBase.getInstance().isConnected())
				new ConnectionPane();
		}
	}

	private class DisconnectAction extends AbstractAction {
		public DisconnectAction() {
			putValue(NAME, "Déconnexion");
			putValue(SHORT_DESCRIPTION, "Se déconnecter de la base de données");
		}

		public void actionPerformed(ActionEvent e) {
			if (DataBase.getInstance().isConnected())
				DataBase.getInstance().closeConnection();
		}
	}

}
